;*****************************************************************************************************
;+
; NAME:
;       IGL_LEGENDITEM
;
; PURPOSE:
;
;       This is a basic vizualisation object which represents a
;       single legend item (text+line/symbol). It is meant to be used
;       as a child of an IGL_Legend object. 
;
;
; AUTHORS:
;
;        RAPHAEL SADOUN
;        Graduate Student
;        Institut d'Astrophysique de Paris
;        98 bis boulevard Arago
;        75014 PARIS FRANCE
;        E-mail: raphael.sadoun@gmail.com
;
; SUPERCLASSES:
;
;       CATDATAATOM (Catalyst Library)
;
; SYNTAX:
;
;       item = Obj_New('IGL_LegendItem')
;
;
; CLASS_STRUCTURE:
;
;       class = {IGL_LegendItem, $      
;           INHERITS CATDATAATOM, $   ; This is a CATDATAATOM object
;           textObject:obj_new(), $   ; The text of the item
;           polyObject:obj_new(), $   ; The polygon to represent the line or symbol
;           xpos:0.0, $               ; The X starting location for drawing the item
;           ypos:0.0, $               ; The Y starting location for drawing the item
;           order:0B, $               ; The order between the text and the polygon
;           hsize:0.0, $              ; The size occupied by the polygon 
;           space:0.0 $               ; The space between the text and the polygon
;          }
;
;
; MODIFICATION_HISTORY:
;
;       Written by: Raphael Sadoun, 24 April 2012
;-
;*****************************************************************************************************
;+
; NAME:
;       IGL_LegendItem::CALCULATELINECOORDINATES
;
; PURPOSE:
;
;       This method calculates the x and y coordinates of the
;       polygon's vertices based on the location of the item
;       and the order between the text and the polygon. It is used
;       internally as a convenience method to easily position the
;       polygon when drawing the legend item.
;
; SYNTAX:
;
;       polycoords = self -> CALCULATELINECOORDINATES()
;
; ARGUMENTS:
;
;       None.
;
; KEYWORDS:
;
;       None.
;-
;*****************************************************************************************************
FUNCTION IGL_LegendItem::CalculateLineCoordinates

  @cat_func_error_handler

  ;; Make sure we have a valid polygon object
  IF (obj_valid(self.polyObject) EQ 0) THEN return, [[0],[0]]

  ;; Get the position of the legend item in normalized coordinates
  self -> ApplyCoords
  cc = CONVERT_COORD(self.xpos,self.ypos,/DATA,/TO_NORMAL)

  ;; Calculate the polygon coordinates in normalized units
  IF (self.order) THEN BEGIN    ; Order = 1 means the text is in front of the polygon
                                ; so we need to offset the polygon by
                                ; the text's width
     
     IF (obj_valid(self.textObject)) THEN width = self.textObject -> GetWidth(/NORMAL) ELSE width = 0
     
     xpos = cc[0]+width+self.space
     ypos = cc[1]
     
  ENDIF ELSE BEGIN ; If the polygon is in front, it has the position of the item

     xpos = cc[0]
     ypos = cc[1]

  ENDELSE

  ;; Check if we have a symbol instead of a line. If that's the
  ;; case, then we position the symbol in the middle of the space
  ;; taken by the polygon which is specified by the HSIZE
  ;; property. Otherwise, we make a line which is HSIZE long.
  self.polyObject -> GetProperty, Psym=psym
  IF (psym EQ 0) THEN BEGIN
     
     xpts = [xpos,xpos+self.hsize]
     ypts = [ypos,ypos]
     
  ENDIF ELSE BEGIN
     
     xpts = xpos+self.hsize/2.0
     ypts = ypos
     
  ENDELSE

  ;; Convert back to data coordinates
  cc = CONVERT_COORD(xpts,ypts,/NORMAL,/TO_DATA)

  ;; Report completion
  self -> Report, /Completed

  RETURN, cc[0:1,*]

END


;*****************************************************************************************************
;+
; NAME:
;       IGL_LegendItem::CALCULATETEXTCOORDINATES
;
; PURPOSE:
;
;       This method calculates the x and y location of the
;       text based on the location of the item and the order between
;       the text and the polygon. It is used internally as a
;       convenience method to easily position the text when drawing
;       the legend item.
;
; SYNTAX:
;
;       polycoords = self -> CALCULATETEXTCOORDINATES()
;
; ARGUMENTS:
;
;       None.
;
; KEYWORDS:
;
;       None.
;-
;*****************************************************************************************************
FUNCTION IGL_LegendItem::CalculateTextCoordinates

  @cat_func_error_handler

  ;; Make sure we have a valid text object
  IF (obj_valid(self.textObject) EQ 0) THEN return, [0,0]

  ;; Get the position of the legend item in normalized coordinates
  self -> ApplyCoords
  cc = CONVERT_COORD(self.xpos,self.ypos,/DATA,/TO_NORMAL)

  ;; Get the text's height in normalized units
  height = self.textObject -> GetHeight(/NORMAL)

  ;; Order = 0 means the text is in front of the polygon
  ;; so we set it's position to that of the item. If the
  ;; polygon is in fron (Order = 0), then we need to offset the text
  ;; by the size of the polygon.
  IF self.order THEN BEGIN
     
     xpos = cc[0]
     ypos = cc[1]-0.5*height
     
  ENDIF ELSE BEGIN
     
     xpos = cc[0]+self.hsize+self.space
     ypos = cc[1]-0.5*height
     
  ENDELSE

  ;; Convert back to data coordinates
  cc = CONVERT_COORD(xpos,ypos,/NORMAL,/TO_DATA)

  ;; Report completion
  self -> Report, /Completed

  RETURN, [cc[0],cc[1]]
  
END

;*****************************************************************************************************
;+
; NAME:
;       IGL_LegendItem::CONTROLPANEL
;
; PURPOSE:
;
;       This method creates a control panel for the graphic.
;
; SYNTAX:
;
;       self -> ControlPanel, baseObject
;
; ARGUMENTS:
;
;       baseObject:    The object reference of a base widget for this control to
;                      be added to. If not supplied, the control panel will be in a
;                      self contained window.
;
; KEYWORDS:
;
;       _EXTRA:       Any keywords appropriate for the CATCONTROLPANEL::INIT method.
;-
;*****************************************************************************************************
PRO IGL_LegendItem::ControlPanel, baseObject, _EXTRA=extraKeywords

   @cat_pro_error_handler

   ;; Create a new control panel
   cp = OBJ_NEW ('CatControlPanel', self, PARENT=baseObject, COLUMN=1, $
                 TITLE='IGL_LegendItem Control Panel', _EXTRA=extraKeywords, /No_Cancel, /No_Apply, /No_OK)

   IF (NOT OBJ_VALID (cp)) THEN RETURN

   aproperties = Obj_New('PROPERTYSHEETWIDGET', cp, Value=self, Name='IGL_LEGENDITEM PROPERTYSHEET', YSize=16)
   aproperties -> SetProperty, Event_Object=self

   ;; Display the control panel if it created its own TLB.
   IF cp -> Created_Own_TLB(tlb) THEN tlb -> Draw, /Center

   self -> Report, /Completed

END


;*****************************************************************************************************
;+
; NAME:
;       IGL_legendItem::DRAW
;
; PURPOSE:
;
;       This method draws the graphic in the current display window.
;
; SYNTAX:
;
;       self -> Draw
;
; ARGUMENTS:
;
;       None.
;
; KEYWORDS:
;
;       _EXTRA:  Any keyword accepted by the CATATOM, IGL_Text and IGL_Polygon
;                draw methods.
;
;-
;*****************************************************************************************************
PRO IGL_LegendItem::Draw, _EXTRA=extra

  @cat_pro_error_handler

  ;; If the legend item is invisible, then return immediately.
  IF self.visible EQ 0 THEN RETURN
  
  ;; Apply the coordinate system.
  self -> ApplyCoords
  
  ;; Draw the polygon.
  IF (obj_valid(self.polyObject)) THEN BEGIN
     
     IF (self.hsize GT 0) THEN BEGIN
        
        pos = self -> CalculateLineCoordinates()
        self.polyObject -> SetProperty, XPTS=pos[0,*], YPTS=pos[1,*]
        self.polyObject -> Draw, _EXTRA=extra
         
     ENDIF
      
  ENDIF
  
  ;; Draw the text
  IF (obj_valid(self.textObject)) THEN BEGIN
     
     pos = self -> CalculateTextCoordinates()
     self.textObject -> SetProperty, X=pos[0], Y=pos[1]
     self.textObject -> Draw, _EXTRA=extra
     
  ENDIF

  ;; Draw the children
  self -> CATATOM::Draw, _EXTRA=extra
  
  ;; Report, completion
  self -> Report, /Completed
  
END


;*****************************************************************************************************
;+
; NAME:
;        IGL_LegendItem::EVENT_HANDLER
;
; PURPOSE:
;
;        This method is the event handler for the IGL_LegendItem object. It will typically
;        be used to respond to events from widget objects created in the CONTROLPANEL
;        method.
;
; SYNTAX:
;
;        This method is called automatically by the event handling mechanism.
;
; ARGUMENTS:
;
;       event: The event structure as described in the IDL help files, except
;              that the ID, TOP and HANDLER tags will be object references.
;
; KEYWORDS:
;
;       None.
;
;-
;*****************************************************************************************************
PRO IGL_LegendItem::EventHandler, event

   @cat_pro_error_handler

   ; Get the name of the widget generating the event. Branch on this.
   event.ID -> GetProperty, Name=eventName
   
   CASE eventName OF


      'IGL_LEGENDITEM PROPERTYSHEET': BEGIN

         IF event.type EQ 0 THEN BEGIN
            
            CASE StrUpCase(event.identifier) OF

               'TCOLOR': BEGIN

                  event.component -> GetProperty, TColor=color
                  event.id -> GetProperty, ID=group_leader
                  color = PickColorName(color, Group_Leader=group_leader)
                  event.component -> SetProperty, TColor=color

                  ; Refresh the graphics hierarchy.
                  IGL_RefreshDraw, event.component, /Buffered_Output

               END

               'PCOLOR': BEGIN

                  event.component -> GetProperty, PColor=color
                  event.id -> GetProperty, ID=group_leader
                  color = PickColorName(color, Group_Leader=group_leader)
                  event.component -> SetProperty, Pcolor=color

                  ; Refresh the graphics hierarchy.
                  IGL_RefreshDraw, event.component, /Buffered_Output

               END

               ELSE: BEGIN

                  component = event.component
                  identifier = event.identifier
                  event.id -> GetProperty, Value=value, Component=component, Property_Value=identifier
                  event.component -> SetPropertyByIdentifier, identifier, value

                  ; Refresh the graphics hierarchy.
                  IF OBJ_VALID(event.component) THEN IGL_RefreshDraw, event.component, /Buffered_Output

               END

            ENDCASE

         ENDIF                  ; of BUTTON DOWN EVENT

      END                   

      ;; If you can't handle the event here. Pass it along to superclass EventHandler
      ELSE: self -> CATDATAATOM::EventHandler, event

   ENDCASE

   ;; Report completion
   IF Obj_Valid(self) THEN self -> Report, /Completed

END


;*****************************************************************************************************
;+
; NAME:
;       IGL_legendItem::GETHEIGHT
;
; PURPOSE:
;
;       This method returns the vertical space used by the item on the
;       display. It assumes a valid display window when called.
;
; SYNTAX:
;
;       height = self -> GetHeight()
;
; ARGUMENTS:
;
;       None.
;
; KEYWORDS:
;
;       DATA:    Set this keyword to have the result returned in data coordinates.
;
;       DEVICE:  Set this keyword to have the result returned in device coordinates.
;
;       NORMAL:  Set this keyword to have the result returned in
;                normalized coordinates (this is the default).
;
;-
;*****************************************************************************************************
FUNCTION IGL_LegendItem::GetHeight, DATA=data, DEVICE=device, NORMAL=normal

  @cat_func_error_handler

  IF (obj_valid(self.textObject)) THEN height = self.textObject -> GetHeight(DATA=data,DEVICE=device,NORMAL=normal) $
  ELSE height = 0.0

  ;; Report completion
  self -> Report, /Completed

  RETURN, height
  
END


;*****************************************************************************************************
;+
; NAME:
;       IGL_legendItem::GETWIDTH
;
; PURPOSE:
;
;       This method returns the horizontal space used by the item on the
;       display. It assumes a valid display window when called.
;
; SYNTAX:
;
;       height = self -> GetWidth()
;
; ARGUMENTS:
;
;       None.
;
; KEYWORDS:
;
;       DATA:    Set this keyword to have the result returned in data coordinates.
;
;       DEVICE:  Set this keyword to have the result returned in device coordinates.
;
;       NORMAL:  Set this keyword to have the result returned in
;                normalized coordinates (this is the default).
;
;-
;*****************************************************************************************************
FUNCTION IGL_LegendItem::GetWidth, DEVICE=device, NORMAL=normal, DATA=data

  @cat_func_error_handler

  IF (obj_valid(self.textObject)) THEN textWidth = self.textObject -> GetWidth(/NORMAL) ELSE textWidth = 0
  
  itemWidth = textWidth+self.hsize+self.space

  ;; Calculate the width in the desired units
  
  IF keyword_set(data) THEN BEGIN ; DATA units
     
     IF OBJ_VALID(self._coords) THEN BEGIN 
        self._coords -> GetProperty, XRANGE=xr, YRANGE=yr, POSITION=pos
        width = Abs(xr[1] - xr[0]) / (Abs(pos[2]-pos[0])) * itemWidth
     ENDIF ELSE width = 0
     
  ENDIF
  
  IF keyword_set(device) THEN width = itemWidth*!D.X_SIZE ; DEVICE units
  
  IF keyword_set(normal) THEN width = itemWidth           ; NORMALIZED units

  ;; If no keyword is set, use normalized coordinates
  IF N_Elements(width) EQ 0 THEN width = itemWidth

  ;; Report completion
  self -> Report, /Completed
  
  RETURN, width

END


;*****************************************************************************************************
;+
; NAME:
;       IGL_LegendItem::GETPROPERTY
;
; PURPOSE:
;
;       This method is used to get the object's properties.
;
; SYNTAX:
;
;       self -> GetProperty
;
; ARGUMENTS:
;
;     None.
;
; KEYWORDS:
;
;     XPOS:         The X location of the legend item.
;
;     YPOS:         The Y location of the legend item.
;
;     HSIZE:        The space used by the polygon (line/symbol) in
;                   normalized units.
;
;     SPACE:        The space between the text and the polygon in
;                   normalized units.
;
;     PCOLOR:       The color of the polygon (line/symbol).
;
;     TEXT:         The text to display as the legend.
;
;     TCOLOR:       The color of the text.
;
;     ORDER:        Flag indicating if the text is in front of the polygon (order=1).
;
;     VISIBLE:      Flag indicating if the object is visible.
;
;     _REF_EXTRA:   Any keywords appropriate for the CATDATAATOM, IGL_Text
;                   and IGL_Polygon GetProperty methods.
;-
;*****************************************************************************************************
PRO IGL_LegendItem::GetProperty, LINESTYLE=linestyle, $
                                 HSIZE=hsize, $
                                 PSYM=psym, $
                                 SYMSIZE=symsize, $
                                 FONT=font, $
                                 THICK=thick, $
                                 CHARSIZE=charsize, $
                                 CHARTHICK=charthick, $
                                 SPACE=space, $
                                 XPOS=xpos, $
                                 YPOS=ypos, $
                                 TCOLOR=tcolor, $
                                 PCOLOR=pcolor, $
                                 TEXT=text, $
                                 ORDER=order, $
                                 ORIENTATION=orientation, $
                                 VISIBLE=visible, $
                                 DELETE=delete, $
                                 _REF_EXTRA=extraKeywords

   @cat_pro_error_handler

   ;; Polygon properties
   IF (obj_valid(self.polyObject)) THEN BEGIN
      
      self.polyObject -> GetProperty, LINESTYLE=linestyle, $
                                      PSYM=psym, $
                                      SYMSIZE=symsize, $
                                      THICKNESS=thick, $
                                      PCOLORS=pcolor
      
   ENDIF

   ;; Text properties
   IF (obj_valid(self.textObject)) THEN BEGIN
      
      self.textObject -> GetProperty, CHARSIZE=charsize, $
                                      THICKNESS=charthick, $
                                      COLOR=tcolor, $
                                      FONT=font, $
                                      TEXT=text, $
                                      ORIENTATION=orientation
      
   ENDIF

   IF (arg_present(hsize)) THEN hsize = self.hsize
   IF (arg_present(space)) THEN space = self.space
   IF (arg_present(order)) THEN order = self.order
   IF (arg_present(xpos)) THEN xpos = self.xpos
   IF (arg_present(ypos)) THEN ypos = self.ypos
   IF (arg_present(visible)) THEN visible = self.visible
   IF (arg_present(delete)) THEN delete = 0 ; Dummy for RegisterProperty functionality

   IF (N_ELEMENTS(extraKeywords) GT 0) THEN self -> CATDATAATOM::GetProperty, _EXTRA=extraKeywords

   self -> Report, /Completed

END


;*****************************************************************************************************
;+
; NAME:
;       IGL_LegendItem::SETPROPERTY
;
; PURPOSE:
;
;       This method is used to set the object's properties.
;
; SYNTAX:
;
;       self -> SetProperty
;
; ARGUMENTS:
;
;     None.
;
; KEYWORDS:
;
;     XPOS:         The X location of the legend item.
;
;     YPOS:         The Y location of the legend item.
;
;     HSIZE:        The space used by the polygon (line/symbol) in
;                   normalized units.
;
;     SPACE:        The space between the text and the polygon in
;                   normalized units.
;
;     PCOLOR:       The color of the polygon (line/symbol).
;
;     TEXT:         The text to display as the legend.
;
;     TCOLOR:       The color of the text.
;
;     ORDER:        Flag indicating if the text is in front of the polygon (order=1).
;
;     VISIBLE:      Flag indicating if the object is visible.
;
;     DELETE:       Set this keyword to destroy the object.
;
;     _EXTRA:       Any keywords appropriate for the CATDATAATOM, IGL_Text
;                   and IGL_Polygon SetProperty methods.
;
;-
;*****************************************************************************************************
PRO IGL_LegendItem::SetProperty, LINESTYLE=linestyle, $
                                 HSIZE=hsize, $
                                 PSYM=psym, $
                                 SYMSIZE=symsize, $
                                 SPACE=space, $
                                 THICK=thick, $
                                 FONT=font, $
                                 CHARSIZE=charsize, $
                                 CHARTHICK=charthick, $
                                 TCOLOR=tcolor, $
                                 PCOLOR=pcolor, $
                                 TEXT=text, $
                                 ORDER=order, $
                                 XPOS=xpos, $
                                 YPOS=ypos, $
                                 ORIENTATION=orientation, $
                                 COORD_OBJECT=coord_object, $
                                 VISIBLE=visible, $
                                 DELETE=delete, $
                                 _EXTRA=extraKeywords

   @cat_pro_error_handler

   ;; Polygon properties
   IF (obj_valid(self.polyObject)) THEN BEGIN

      self.polyObject -> SetProperty, LINESTYLE=linestyle, $
                                      PSYM=psym, $
                                      SYMSIZE=symsize, $
                                      PCOLORS=pcolor, $
                                      THICKNESS=thick, $
                                      COORD_OBJECT=coord_object

      IF (n_elements(pcolor) NE 0) THEN BEGIN
         
         self -> SetPropertyAttribute, 'PCOLOR', userdef=CapFirstLetter(pcolor)
         IF (obj_valid(self._controlPanel)) THEN self._controlPanel -> Refresh_Properties, Properties='PCOLOR'
         
      ENDIF
      
   ENDIF

   ;; Text properties
   IF (obj_valid(self.textObject)) THEN BEGIN

      self.textObject -> SetProperty, CHARSIZE=charsize, $
                                      THICKNESS=charthick, $
                                      FONT=font, $
                                      TEXT=text, $
                                      COLOR=tcolor, $
                                      ORIENTATION=orientation, $
                                      COORD_OBJECT=coord_object

      IF (n_elements(tcolor) NE 0) THEN BEGIN
         
         self -> SetPropertyAttribute, 'TCOLOR', userdef=CapFirstLetter(tcolor)
         IF (obj_valid(self._controlPanel)) THEN self._controlPanel -> Refresh_Properties, Properties='TCOLOR'
         
      ENDIF
      
   ENDIF
   
   IF (n_elements(hsize) NE 0) THEN self.hsize = 0 > hsize < 1
   IF (n_elements(space) NE 0) THEN self.space = 0 > space < 1
   IF (n_elements(order) NE 0) THEN self.order = keyword_set(order)
   IF (n_elements(xpos) NE 0) THEN self.xpos = xpos
   IF (n_elements(ypos) NE 0) THEN self.ypos = ypos
   IF (n_elements(visible) NE 0) THEN self.visible = keyword_set(visible)
 
   self -> CATDATAATOM::SetProperty, COORD_OBJECT=coord_object, _EXTRA=extraKeywords

   IF (keyword_set(delete)) THEN BEGIN
      self -> SetProperty, Visible=0
      IGL_RefreshDraw, self, /Buffered_Output
      Obj_Destroy, self._controlPanel
      self -> GetProperty, Parent=parents
      self -> SendMessage, 'OBJECT_DELETED', DATA=self
      FOR j=0,N_Elements(parents)-1 DO IF OBJ_VALID(parents[j]) THEN parents[j] -> Remove, self
      Obj_Destroy, self
      RETURN
   ENDIF

   IF OBJ_VALID(self) THEN self -> Report, /Completed

END


;*****************************************************************************************************
;+
; NAME:
;       IGL_LegendItem::CLEANUP
;
; PURPOSE:
;
;       This is the IGL_LegendItem object class destructor method.
;
; SYNTAX:
;
;       Called automatically when the object is destroyed.
;
;
; ARGUMENTS:
;
;     None.
;
; KEYWORDS:
;
;     None.
;-
;*****************************************************************************************************
PRO IGL_LegendItem::CLEANUP

   @cat_pro_error_handler

   ;; Cleanup the text and polygon object
   IF (obj_valid(self.textObject)) THEN self.textObject -> RemoveParent, self
   IF (obj_valid(self.polyObject)) THEN self.polyObject -> RemoveParent, self

   ;; Cleanup the superclass
   self -> CATDATAATOM::CLEANUP

   ;; Report completion
   self -> Report, /Completed
   
END


;*****************************************************************************************************
;+
; NAME:
;       IGL_LegendItem::INIT
;
; PURPOSE:
;
;       This is the IGL_LegendItem object class initialization method
;
; SYNTAX:
;
;       Called automatically when the object is created.
;
; ARGUMENTS:
;
;     None.
;
; KEYWORDS:
;
;     XPOS:     The X location of the legend item.
;
;     YPOS:     The Y location of the legend item.
;
;     HSIZE:    The space used by the polygon (line/symbol) in
;               normalized units. The default is 0.1.
;
;     SPACE:    The space between the text and the polygon in
;               normalized units. The default is 0.02.
;
;     PCOLOR:   The color of the polygon (line/symbol).
;
;     TEXT:     The text to display as the legend.
;
;     TCOLOR:   The color of the text.
;
;     ORDER:    Flag indicating if the text is in front of the polygon (order=1).
;
;     _EXTRA:   Any keywords appropriate for the CATDATAATOM, IGL_Text
;               and IGL_Polygon INIT methods.
;-
;*****************************************************************************************************
FUNCTION IGL_LegendItem::INIT, XPOS=xpos, $
                               YPOS=ypos, $
                               TEXT=text, $
                               LINESTYLE=linestyle, $
                               PSYM=psym, $
                               SYMSIZE=symsize, $
                               TCOLOR=tcolor, $
                               PCOLOR=pcolor, $
                               HSIZE=hsize, $
                               CHARSIZE=charsize, $
                               CHARTHICK=charthick, $
                               FONT=font, $
                               THICK=thick, $
                               SPACE=space, $
                               ORDER=order, $
                               ORIENTATION=orientation, $
                               COORD_OBJECT=coord_object, $
                               _Extra=extraKeywords


   @cat_func_error_handler

   ;; Default keyword values
   IF (n_elements(xpos) EQ 0) THEN xpos = 0.0
   IF (n_elements(ypos) EQ 0) THEN ypos = 0.0
   IF (n_elements(linestyle) EQ 0) THEN linestyle = !IGL_P.linestyle
   IF (n_elements(psym) EQ 0) THEN psym = !IGL_P.psym
   IF (n_elements(symsize) EQ 0) THEN symsize = (!IGL_P.symsize EQ 0) ? 1 : !IGL_P.symsize
   IF (n_elements(thick) EQ 0) THEN thick = (!IGL_P.thick EQ 0) ? 1 : !IGL_P.thick
   IF (n_elements(pColor) EQ 0) THEN pColor = !IGL_P.color
   IF (n_elements(tColor) EQ 0) THEN tColor = !IGL_P.color
   IF (n_elements(hsize) EQ 0) THEN hsize = 0.1
   IF (n_elements(space) EQ 0) THEN space = 0.02
   IF (n_elements(text) EQ 0) THEN text = ''
   IF (n_elements(charsize) EQ 0) THEN charsize = (!IGL_P.charsize EQ 0) ? 1: !IGL_P.charsize
   IF (n_elements(charthick) EQ 0) THEN charthick = (!IGL_P.charthick EQ 0) ? 1 : !IGL_P.charthick
   IF (n_elements(font) EQ 0) THEN font = !IGL_P.font+1

   ;; Call superclass INIT method
   ok = self -> CATDATAATOM::Init(COORD_OBJECT=coord_object,_Extra=extraKeywords)

   IF (NOT ok) THEN RETURN, 0
   
   ;; Initialize the text object
   textObject = obj_new('IGL_TEXT',text,$
                        COORD_OBJECT=coord_object, $
                        ALIGNMENT=0, $
                        COLOR=tColor, $
                        FONT=( 0 > font < 2 ), $
                        CHARSIZE=( charsize > 0.1), $
                        ORIENTATION=orientation, $
                        THICKNESS=( charthick > 1) $
                       )
   textObject -> AddParent, self
   self.textObject = textObject

   ;; Initialize the polygon object
   polyObject = obj_new('IGL_POLYGON', $
                        COORD_OBJECT=coord_object, $
                        LINESTYLE=( 0 > linestyle < 5 ), $
                        PSYM=( 0 > psym < 46 ), $
                        SYMSIZE=( symsize > 0.1), $
                        THICKNESS=( thick > 1), $
                        PCOLORS=pColor $
                       )
   polyObject -> AddParent, self
   self.polyObject = polyObject

   ;; Load object
   self.xpos = xpos
   self.ypos = ypos
   self.space = 0 > space < 1
   self.hsize = 0 > hsize < 1
   self.order = keyword_set(order)
   self.visible = 1

   ;; Change default name and description for the CATDATAATOM object
   self -> SetProperty, name='Legend item', description='Single legend element'

   ;; Set up editable properties
   self -> SetPropertyAttribute, 'NAME', sensitive=0
   self -> SetPropertyAttribute, 'DESCRIPTION', sensitive=0
   self -> RegisterProperty, 'DELETE', /boolean, name='Delete Object'
   self -> RegisterProperty, 'PCOLOR', 0, name='Color', userdef=CapFirstLetter(pColor)
   self -> RegisterProperty, 'LINESTYLE', name='Line Style', /linestyle
   self -> RegisterProperty, 'HSIZE', name='Size', /float, valid_range=[0.0,1.0]
   self -> RegisterProperty, 'SPACE', name='Space', /float, valid_range=[0.0,1.0]
   self -> RegisterProperty, 'PSYM', 9, name='Symbol', enumlist=IGL_GetSymbolList()
   self -> RegisterProperty, 'SYMSIZE', /float, name='Symbol size', valid_range=[0.1,10.0]
   self -> RegisterProperty, 'THICK', name='Thickness', /integer, valid_range=[1,10]
   self -> RegisterProperty, 'TEXT', /string, name='Text'
   self -> RegisterProperty, 'ORDER', /boolean, name='Text in front'
   self -> RegisterProperty, 'TCOLOR', 0, name='Text Color', userdef=CapFirstLetter(tColor)
   self -> RegisterProperty, 'FONT', name='Text Font', enumlist=['Herschey','Hardware','TrueType']
   self -> RegisterProperty, 'ORIENTATION', /float, name='Text Orientation', valid_range=[0.0,360.0]
   self -> RegisterProperty, 'CHARSIZE', name='Text Size', /float, valid_range=[0.1,10.0]
   self -> RegisterProperty, 'CHARTHICK', name='Text Thickness', /integer, valid_range=[1,10]

   ;; Report completion
   self -> Report, /Completed

   RETURN, 1

END


;*****************************************************************************************************
;
; NAME:
;       IGL_LEGENDITEM CLASS DEFINITION
;
; PURPOSE:
;
;       This is the IGL_LegendItem object's structure definition code.
;
;*****************************************************************************************************
PRO IGL_LegendItem__DEFINE, class

  COMPILE_OPT idl2, HIDDEN

  class = {IGL_LegendItem, $      
           INHERITS CATDATAATOM, $   ; This is a CATDATAATOM object
           textObject:obj_new(), $   ; The text of the item
           polyObject:obj_new(), $   ; The polygon to represent the line or symbol
           xpos:0.0, $               ; The X starting location for drawing the item
           ypos:0.0, $               ; The Y starting location for drawing the item
           order:0B, $               ; The order between the text and the polygon
           hsize:0.0, $              ; The size occupied by the polygon 
           space:0.0, $              ; The space between the text and the polygon
           visible:0B $              ; Flag indicating if the object is visible.
          }

  struct_hide, class

END
